package com.bestcem.xm.survey.export.type;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.bestcem.xm.survey.export.BaseTypeHandler;
import com.bestcem.xm.survey.grpc.client.dto.QstructsDto;
import org.springframework.stereotype.Component;

import java.util.*;
import java.util.stream.Collectors;

import static com.bestcem.xm.survey.enums.QuestionTypeEnum.QUESTION_TYPE_EVALUATION;

/**
 * 评价题
 */
@Component
public class EvaluationHandler implements BaseTypeHandler {

    @Override
    public Map<String, String> getSelectColumnChangeDictV2(JSONObject data, String dtype) {
        Map<String, String> column_change_dict = new HashMap();
        column_change_dict.put(getSelectRealcolV2(data, null), getSelectReadablecolV2(data, null));
        List<JSONObject> sorted_tag_list = getSortedTagList(data);
        sorted_tag_list.forEach(v -> column_change_dict.put(getSelectRealcolV2(data, v), getSelectReadablecolV2(data, v)));
        return column_change_dict;
    }


    private String getSelectRealcolV2(JSONObject data, JSONObject tag) {
        //cid:题目可见编号
        if (Objects.isNull(tag)) {
            return data.getString("cid");
        }
        return String.format("%s__%s", data.get("cid"), tag.get("oid"));
    }

    private String getSelectReadablecolV2(JSONObject data, JSONObject item) {
        if (Objects.isNull(item)) {
            return (String) ((Map) data.getOrDefault("current_template", Collections.emptyMap())).get("title");
        }
        return String.format("%s__%s", BaseTypeHandler.clearHtml((String) ((Map) data.getOrDefault("current_template", Collections.emptyMap())).get("title")), BaseTypeHandler.clearHtml(item.getString("title")));
    }


    @Override
    public Map<String, String> getOpenColumnChangeDictV2(JSONObject data) {
        Map<String, String> change_dict = new HashMap();
        change_dict.put(getOpenRealcolV2(data, true), getOpenReadablecolV2(data, true));
        if ((Boolean) data.getOrDefault("write_evaluate", false)) {
            change_dict.put(getOpenRealcolV2(data, false), getOpenReadablecolV2(data, false));
        }
        return change_dict;
    }

    private String getOpenReadablecolV2(JSONObject data, boolean tag) {
        String title = BaseTypeHandler.clearHtml((String) ((Map) data.getOrDefault("current_template", Collections.emptyMap())).get("title"));
        if (tag) {
            return String.format("%s__标签", title);
        }
        return String.format("%s__开放", title);
    }

    private String getOpenRealcolV2(JSONObject data, boolean tag) {
        if (tag) {
            return String.format("%s__tag", data.getString("cid"));
        }
        return String.format("%s__open", data.getString("cid"));
    }

    @Override
    public List<String> getSelectColumnListV2(JSONObject data, String dtype) {
        List<String> res = new ArrayList();
        res.add(getSelectRealcolV2(data, null));
        List<JSONObject> tag_list = getSortedTagList(data);
        tag_list.forEach(v -> res.add(getSelectRealcolV2(data, v)));
        return res;
    }

    @Override
    public List<String> getOpenColumnListV2(JSONObject data) {
        List<String> res = new ArrayList();
        res.add(getOpenRealcolV2(data, true));
        if ((Boolean) data.getOrDefault("write_evaluate", false)) {
            res.add(getOpenRealcolV2(data, false));
        }
        return res;
    }

    @Override
    public Map<String, Map<Object, Object>> getConvertTableV2(JSONObject q) {
        Map<String, Map<Object, Object>> table = new HashMap();
        List<JSONObject> tag_list = (List<JSONObject>) ((Map) q.getJSONObject("current_template").getOrDefault("tagList", Collections.emptyMap())).values().stream().collect(Collectors.toList());
        tag_list.forEach(v -> {
            Map<Object, Object> res = new HashMap<>(4);
            //Base.UNSELECT_OPTION_NAN 可以理解为null
            res.put(0, null);
            res.put(1, v.getString("title"));
            table.put(getSelectRealcolV2(q, v), res);
        });
        return table;
    }

    @Override
    public Map<Object, Object> getSelectAnswerDictV2(JSONObject dataValue, Object answer, String dtype, Boolean score_apply_type) {
        Map<Object, Object> data = new HashMap<>();
        if (Objects.isNull(answer)) {
            //np.nan 可以理解为null
            data.put(getSelectRealcolV2(dataValue, null), null);
            List<JSONObject> sorted_tag_list = getSortedTagList(dataValue);
            //np.nan 可以理解为null
            sorted_tag_list.forEach(v -> data.put(getSelectRealcolV2(dataValue, v), null));
        } else {
            JSONObject answers = ((JSONObject) answer);
            Integer score = answers.getInteger("score");
            JSONArray tagsId = answers.getJSONArray("tagsId");
            if (Objects.nonNull(score)) {
                data.put(getSelectRealcolV2(dataValue, null), score);
                List<JSONObject> sorted_tag_list = getSortedTagList(dataValue);
                sorted_tag_list.forEach(v -> {
                    if (tagsId.contains(v.get("gid"))) {
                        if ("not01".equals(dtype) || "anothernot01".equals(dtype)) {
                            data.put(getSelectRealcolV2(dataValue, v), v.getString("oid"));
                        } else {
                            data.put(getSelectRealcolV2(dataValue, v), 1);
                        }
                    } else if ("not01".equals(dtype) || "anothernot01".equals(dtype)) {
                        //np.nan 可以理解为null
                        data.put(getSelectRealcolV2(dataValue, v), null);
                    } else {
                        data.put(getSelectRealcolV2(dataValue, v), 0);
                    }
                });
            } else if (StrUtil.isNotEmpty(answers.getString("no_apply"))) {
                //np.nan 可以理解为null
                data.put(getSelectRealcolV2(dataValue, null), score_apply_type ? answers.getString("no_apply") : null);
            } else {
                data.put(getSelectRealcolV2(dataValue, null), null);
                List<JSONObject> sorted_tag_list = getSortedTagList(dataValue);
                sorted_tag_list.forEach(v -> data.put(getSelectRealcolV2(dataValue, v), null));
            }
        }
        return data;
    }

    @Override
    public Map<Object, Object> getOpenAnswerDictV2(JSONObject dataValue, Object answer) {
        Map<Object, Object> data = new HashMap<>();
        if (Objects.isNull(answer)) {
            //np.nan 可以理解为null
            data.put(getOpenRealcolV2(dataValue, true), null);
            data.put(getOpenRealcolV2(dataValue, false), null);
        } else {
            JSONObject answers = (JSONObject) answer;
            List<Integer> tagsId = (List<Integer>) answers.get("tagsId");
            if (CollUtil.isNotEmpty(tagsId)) {
                List<String> tags = new ArrayList();
                JSONObject tag_list = Optional.ofNullable(Optional.ofNullable(dataValue.getJSONObject("current_template")).orElse(new JSONObject())
                        .getJSONObject("tagList")).orElse(new JSONObject());
                tagsId.forEach(tag_gid -> {
                    if (ObjectUtil.isNotEmpty(tag_list.get(tag_gid))) {
                        tags.add(BaseTypeHandler.clearHtml((String) tag_list.getJSONObject(String.valueOf(tag_gid)).getOrDefault("title", "")));
                    }
                });
                //标签
                data.put(getOpenRealcolV2(dataValue, true), String.join(",", tags));
                //评价
                data.put(getOpenRealcolV2(dataValue, false), BaseTypeHandler.clearHtml((String) answers.getOrDefault("open", "")));
            } else {
                data.put(getOpenRealcolV2(dataValue, true), StrUtil.join(",", answers.getOrDefault("tags", Collections.emptyList())));
                data.put(getOpenRealcolV2(dataValue, false), BaseTypeHandler.clearHtml((String) answers.getOrDefault("open", "")));
            }
        }
        return data;
    }

    @Override
    public List<List<String>> getVarLabelsV2(JSONObject dataValue, boolean not01, boolean need_title) {
        List<List<String>> data = new ArrayList<>();
        List<String> var_list = new ArrayList(), val_list = new ArrayList(), head_list = new ArrayList();
        var_list.add(String.format("VARIABLE LABELS %s '%s:分值'.", getSelectCol(dataValue, null), getTitles(dataValue, null, null, false)));
        List<JSONObject> sorted_tag_list = getSortedTagList(dataValue);
        sorted_tag_list.forEach(tag -> {
            var_list.add(String.format("VARIABLE LABELS %s '%s:%s'.", getSelectCol(dataValue, tag), getTitles(dataValue, null, null, false), getUnquotedStr(dataValue.getString("title"), false)));
            head_list.add(String.format("%s__%s", dataValue.get("cid"), tag.get("oid")));
        });
        getValItemsV2(dataValue, head_list, val_list, not01, true);
        data.add(var_list);
        data.add(val_list);
        return data;
    }

    private Object getSelectCol(JSONObject dataValue, JSONObject tag) {
        if (Objects.isNull(tag)) {
            return dataValue.getString("cid");
        }
        return String.format("%s_%s", dataValue.getString("cid"), tag.getString("oid"));
    }

    @Override
    public List<String> getSpssCodeV2(JSONObject param, QstructsDto qstruct) {
        //交叉表框架代码导出
        List<String> head_list = new ArrayList();
        head_list.add(param.getString("cid"));
        //老版本的评价题，不带题目cid_标签cid
        List<JSONObject> sorted_tag_list = getSortedTagList(param);
        sorted_tag_list.forEach(tag -> head_list.add(String.format("%s__%s", param.getString("cid"), tag.getString("oid"))));
        head_list.add(String.format("$%s__tag", param.getString("cid")));
        if (ObjectUtil.isNotEmpty(param.getJSONObject("question").get("write_evaluate"))) {
            head_list.add(String.format("%s__open", param.getString("cid")));
        }
        return head_list;
    }

    @Override
    public String getQuestionTypeValue() {
        return QUESTION_TYPE_EVALUATION.getValue();
    }
}
